package com.autumn.config.client.trace;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Map;
import java.util.UUID;

import org.springframework.beans.factory.config.RuntimeBeanReference;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.GenericBeanDefinition;
import org.springframework.core.type.AnnotationMetadata;

import com.autumn.mq.event.EventTypeEnum;
import com.autumn.mq.event.IEventData;
import com.autumn.mq.event.IEventHandler;
import com.autumn.mq.event.IEventHandlerConfigureInfo;
import com.autumn.mq.rabbit.register.AutumnRabbitBeanDefinitionRegisterManager;
import com.autumn.mq.rabbit.register.AutumnRabbitConnectionInfo;
import com.autumn.spring.boot.bean.AbstractImportBeanDefinitionRegister;
import com.autumn.spring.boot.properties.AutumnCloudProperties;
import com.autumn.spring.boot.properties.PropertiesConstant;
import com.autumn.util.AutumnContextUtils;
import com.autumn.util.ExceptionUtils;
import com.autumn.util.StringUtils;

/**
 * 配置客户端 Bean 定义注册器
 * 
 * @author 老码农
 *         <p>
 *         Description
 *         </p>
 * @date 2018-01-25 22:22:16
 */
public class AutumnCloudConfigTraceClientRabbitBeanDefinitionRegister extends AbstractImportBeanDefinitionRegister {

	private IEventHandlerConfigureInfo createEventHandlerConfigureInfo(String serviceId) {
		return new IEventHandlerConfigureInfo() {

			@Override
			public String getName() {
				return AutumnCloudConfigTraceMessage.EVENT_NAME + "." + serviceId + "."
						+ UUID.randomUUID().toString().replace("-", "");
			}

			@Override
			public String getRoutingKey() {
				return null;
			}

			@Override
			public String getExchangeSuffix() {
				return AutumnCloudConfigTraceMessage.EVENT_NAME;
			}

			@Override
			public EventTypeEnum getEventType() {
				return EventTypeEnum.BROADCAST;
			}

			@Override
			public Class<? extends IEventData> getEventDataType() {
				return AutumnCloudConfigTraceMessage.class;
			}

			@Override
			public int getConcurrentConsumers() {
				return 1;
			}

			@Override
			public Class<? extends IEventHandler<?>> getEventHandlerType() {
				return AutumnCloudConfigTraceHandler.class;
			}
		};
	}

	@Override
	public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
		String enabledCloudConfig = this.getEnvironment().getProperty(AutumnCloudProperties.Config.PREFIX_CONFIG  + ".enabled");
		if (!StringUtils.isNullOrBlank(enabledCloudConfig) && "false".equalsIgnoreCase(enabledCloudConfig.trim())) {
			return;
		}
		enabledCloudConfig = this.getEnvironment().getProperty(AutumnCloudProperties.Config.PREFIX_CONFIG + ".profile");
		if (StringUtils.isNullOrBlank(enabledCloudConfig)) {
			return;
		}
		enabledCloudConfig = this.getEnvironment().getProperty(AutumnCloudProperties.Config.PREFIX_CONFIG + ".label");
		if (StringUtils.isNullOrBlank(enabledCloudConfig)) {
			return;
		}
		
		AutumnRabbitBeanDefinitionRegisterManager regManager = new AutumnRabbitBeanDefinitionRegisterManager(
				this.getEnvironment(), this.getResourceLoader(), registry);

		String rabbitUserName = this.getEnvironment()
				.getProperty(PropertiesConstant.AUTUMN_MESSAGE_RABBIT_MQ_PROPERTIES_PREFIX + ".username");
		if (rabbitUserName == null) {
			this.logger.warn(
					"本地未配置或未能从配置服务器中获取 " + PropertiesConstant.AUTUMN_MESSAGE_RABBIT_MQ_PROPERTIES_PREFIX + " 的配置信息。");
			return;
		}

		String serviceId = this.getEnvironment().getProperty(AutumnContextUtils.PROPERTIES_SPRING_APPLICATION_NAME);
		if (StringUtils.isNullOrBlank(serviceId)) {
			ExceptionUtils.throwConfigureException("未配置 " + AutumnContextUtils.PROPERTIES_SPRING_APPLICATION_NAME);
		}

		// 本地不需要配置，根据配置中心自动返回
		AutumnRabbitConnectionInfo info = new AutumnRabbitConnectionInfo();
		info.setBeanPrefix(PropertiesConstant.AUTUMN_MESSAGE_BENA_PREFIX);
		info.setPropertiesPrefix(PropertiesConstant.AUTUMN_MESSAGE_RABBIT_MQ_PROPERTIES_PREFIX);

		Collection<IEventHandlerConfigureInfo> eventHandlerInfos = new ArrayList<>();
		eventHandlerInfos.add(createEventHandlerConfigureInfo(serviceId));

		info.setEventHandlerInfos(eventHandlerInfos);
		info.setPrimary(false);

		Map<String, Object> map = regManager.getRegisterManager()
				.getEnvironmentPropertiesMap(info.getPropertiesPrefix());

		info.setProperties(map);
		regManager.register(info);

		String beanName = regManager.getRegisterManager().generateBeanName(AutumnCloudConfigTraceHandler.class);
		if (!registry.containsBeanDefinition(beanName)) {
			GenericBeanDefinition definition = regManager.getRegisterManager()
					.createBeanDefinition(AutumnCloudConfigTraceHandler.class, null, null, null);
			definition.setPrimary(true);

			definition.getConstructorArgumentValues()
					.addGenericArgumentValue(new RuntimeBeanReference(info.getMqEventBusBeanName()));
			definition.getConstructorArgumentValues().addGenericArgumentValue(info);
			definition.getConstructorArgumentValues().addGenericArgumentValue(serviceId);

			regManager.getRegisterManager().registerBean(beanName, definition);
		}

	}

}
